package cn.map.linkedhashmap;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

// https://www.jb51.net/program/308020x99.htm
public class Demo02 {
    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        list.add(new User(1, "张三", "我是张三01"));
        list.add(new User(2, "张三", "我是张三02"));
        list.add(new User(3, "李四", "我是李四01"));
        list.add(new User(4, "李四", "我是李四02"));
        list.add(new User(5, "王五", "我是王五01"));
        list.add(new User(6, "王五", "我是王五02"));
        // List转Map(无序-默认)
        // List转Map有两种Map格式，分别是 Map<String, User>和 Map<String, List>
        // 2.1 List转Map<String, User>  转换成Map<String, User>我们需要使用到Collectors.toMap方法：

        //通过名字进行分组，如果名字重复的话只取第一个：List转Map<String, User>
        //通过名字进行分组，如果名字重复的话只取第一个：List转Map<String, User>
        //通过名字进行分组，如果名字重复的话只取第一个：List转Map<String, User>
        Map<String, User> map01 = list.stream().collect(Collectors.toMap(User::getName, Function.identity(), (u1, u2) -> u1));
        printMap(map01);

        // System.out.println();

        // 2.2 List转Map<String, List<User>>  转换成Map<String, List<User>>我们需要使用到Collectors.groupingBy方法
        //通过名字进行分组，如果名字重复的话就分组成List：List转Map<String, List<User>>
        Map<String, List<User>> map02 = list.stream().collect(Collectors.groupingBy(User::getName));
        // map中打印出来的执行结果并没有按照List中添加的顺序打印的
        printMapList(map02);

        // 3. List转LinkedHashMap(有序)
        // List转LinkedHashMap也有两种Map格式，分别是 LinkedHashMap<String, User>和 LinkedHashMap<String, List>，
        // 3.1 List转LinkedHashMap<String, User> 转换成LinkedHashMap<String, User>我们需要使用到Collectors.toMap方法：
        //通过名字进行分组，如果名字重复的话只取第一个：List转LinkedHashMap<String, User>
        Map<String, User> map03 = list.stream().collect(Collectors.toMap(User::getName, Function.identity(), (u1, u2) -> u1, LinkedHashMap::new));
        printMap(map03);

        // 3.2 List转LinkedHashMap<String, List<User>>
        // 转换成LinkedHashMap<String, List<User>>我们需要使用到Collectors.groupingBy方法：
        // 通过名字进行分组，如果名字重复的话就分组成List：List转LinkedHashMap<String, List<User>>
        Map<String, List<User>> map04 = list.stream().collect(Collectors.groupingBy(User::getName, LinkedHashMap::new, Collectors.toList()));
        // map中打印出来的执行结果是按照List中添加的顺序打印的
        printMapList(map04);
    }

    private static void printMapList(Map<String, List<User>> map){
        map.forEach((k,v)->{
            System.out.println(k);
            v.forEach(System.out::println);
        });
        System.out.println();
    }

    private static void printMap(Map<String, User> map){
        map.forEach((k,v)->System.out.println(k+" : "+v));
        System.out.println();
    }
}
